/*******************************************************************************
 * Copyright (c) 2010 European Software Institute - Tecnalia.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Author - Adri�n Noguero (adrian.noguero@esi.es)
 *     
 *******************************************************************************/
package es.esi.gemde.modelvalidator.ui.dialogs;

import java.util.List;
import java.util.Vector;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import es.esi.gemde.core.CorePlugin;
import es.esi.gemde.core.resources.IGemdeResource.ResourceType;
import es.esi.gemde.modelvalidator.ModelValidatorPlugin;
import es.esi.gemde.modelvalidator.service.IModelValidatorConstraint;

/**
 * A dialog that helps the user to select a list of constraints
 * and a ID prefix for exporting.
 *
 * @author Adrian Noguero (adrian.noguero@tecnalia.com)
 * @version 1.0.4
 * @since 1.0
 *
 */
public class ExportConstraintsDialog extends Dialog {
	
	private CheckboxTreeViewer constraintSelector;
	private List<IModelValidatorConstraint> result;
	private String text;
	private Text prefixText;
	
	private ModifyListener textListener = new ModifyListener () {

		@Override
		public void modifyText(ModifyEvent e) {
			text = prefixText.getText();
		}
		
	};
	
	private ICheckStateListener checkListener = new ICheckStateListener() {

		@Override
		public void checkStateChanged(CheckStateChangedEvent event) {
			// If a category changes
			if (event.getElement() instanceof String) {
				// Find the category item and change the status of the classes.
				TreeItem [] items = constraintSelector.getTree().getItems();
				boolean found = false;
				int i = 0;
				while (!found) {
					if (event.getElement().equals(items[i].getData())) {
						found = true;
					}
					else {
						i++;
					}
				}
				for (TreeItem child : items[i].getItems()) {
					child.setChecked(event.getChecked());
				}
			}
			
			// Clear the result and refill
			result.clear();
			
			for (Object current : constraintSelector.getCheckedElements()) {
				if (current instanceof IModelValidatorConstraint) {
					result.add((IModelValidatorConstraint) current);
				}
			}
		}
		
	};

	/**
	 * Constructor of the Dialog
	 *
	 *@param parentShell the parent shell
	 */
	public ExportConstraintsDialog(Shell parentShell) {
		super(parentShell);
		result = new Vector<IModelValidatorConstraint>();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
	 */
	@Override
	protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText("Export Constraints");
		newShell.setImage(CorePlugin.getImage(CorePlugin.EXPORT_ICON));
		newShell.setSize(400, 300);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite topPanel = (Composite)super.createDialogArea(parent);

		GridLayout layout = (GridLayout)topPanel.getLayout();
		layout.numColumns = 4;
		
		Label idLabel = new Label(topPanel, SWT.NONE);
		GridData idLabelData = new GridData(GridData.FILL_HORIZONTAL);
		idLabelData.horizontalSpan = 1;
		idLabel.setText("ID Prefix:");
		idLabel.setLayoutData(idLabelData);
		
		prefixText = new Text(topPanel, SWT.BORDER | SWT.LEFT);
		GridData prefixTextData = new GridData(GridData.FILL_HORIZONTAL);
		prefixTextData.horizontalSpan = 3;
		prefixText.setText("");
		prefixText.setLayoutData(prefixTextData);
		
		constraintSelector = new CheckboxTreeViewer(topPanel, SWT.SINGLE | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		GridData constraintSelectorData = new GridData(GridData.FILL_BOTH);
		constraintSelectorData.horizontalSpan = 4;
		constraintSelector.getTree().setLayoutData(constraintSelectorData);
		
		// Fill the tree with the constraint repository data
		createTree();
		
		// Add listeners
		constraintSelector.addCheckStateListener(checkListener);
		prefixText.addModifyListener(textListener);
		
		return topPanel;
	}

	/**
	 * Internal method used to fill the constraint selection tree.
	 */
	private void createTree() {
		Tree data = constraintSelector.getTree();
		data.removeAll();
		List<String> categories = ModelValidatorPlugin.getServer().getConstraintCategories();
		List<IModelValidatorConstraint> constraints = ModelValidatorPlugin.getServer().getConstraintRepository();
		for (String category : categories) {
			TreeItem catItem = new TreeItem(data, SWT.NONE);
			catItem.setText(category);
			catItem.setImage(CorePlugin.getImageDescriptor(CorePlugin.CATEGORY_ICON).createImage());
			catItem.setData(category);
			for (IModelValidatorConstraint constraint : constraints) {
				// Show only non-protected constraints!!
				if (constraint.getResourceType().equals(ResourceType.NORMAL)) {
					if (category.equals(constraint.getCategory())) {
						TreeItem constItem = new TreeItem(catItem, SWT.NONE);
						constItem.setText(constraint.getName());
						switch (constraint.getSeverity()) {
						case IStatus.INFO:
							constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON, CorePlugin.INFO_OVERLAY, CorePlugin.TOP_LEFT));
							break;
						case IStatus.WARNING:
							constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON, CorePlugin.WARNING_OVERLAY, CorePlugin.TOP_LEFT));
							break;
						case IStatus.ERROR:
							constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON, CorePlugin.ERROR_OVERLAY, CorePlugin.TOP_LEFT));
							break;
						default:
							constItem.setImage(CorePlugin.getImage(CorePlugin.CONSTRAINT_ICON));
							break;
						}
						constItem.setData(constraint);
					}
				}
			}
		}
	}
	
	/**
	 * This method will return the ID Prefix selected by the user.
	 * Must be called after open().
	 * 
	 * @return the selected ID prefix string.
	 */
	public String getIDPrefix () {
		return text;
	}
	
	/**
	 * This method returns a list with the constraint selected by the user.
	 * Must be called after open().
	 * 
	 * @return the list containing the selected constraints from the repository.
	 */
	public List<IModelValidatorConstraint> getSelectedConstraints() {
		return result;
	}
}
